using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

namespace PddWebAuto
{
    public static class AsyncEx
    {
        /// <summary>
        /// 并发执行
        /// </summary>
        /// <param name="source"></param>
        /// <param name="body"></param>
        /// <param name="maxDegreeOfParallelism"></param>
        /// <param name="scheduler"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Task ParallelForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> body,
            int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded, TaskScheduler scheduler = null)
        {
            if (source == null || !source.Any())
                return Task.CompletedTask;
            var options = new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            };
            if (scheduler != null)
                options.TaskScheduler = scheduler;
            var block = new ActionBlock<T>(body, options);
            foreach (var item in source)
                block.Post(item);
            block.Complete();
            return block.Completion;
        }
    }
}